package com.example.prom.qianduoduo.y2022.controller;

import com.alibaba.fastjson.JSON;
import com.example.prom.qianduoduo.y2022.model.ClinicaltrialsExcelModel;
import com.example.prom.qianduoduo.y2022.model.ClinicaltrialsModel;
import com.example.prom.strategy.excel.CustomCellStyleStrategy;
import com.example.prom.strategy.excel.CustomColumnWidthStrategy;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

import static com.alibaba.excel.EasyExcelFactory.write;

@RestController
@RequestMapping("/clinicaltrials")
public class ClinicaltrialsController {

    private List<ClinicaltrialsExcelModel> allExcelDataList = new ArrayList<>();

    @Autowired
    private RestTemplate restTemplate;



//    @GetMapping("results")
//    public void results(String cond, String oterItem){
//        String url = "https://clinicaltrials.gov/ct2/results?cond="+cond+"&term="+oterItem+"&cntry=&state=&city=&dist=";
//        Object clinicaltrialsModel = restTemplate.getForObject(url, Object.class);
//        System.out.println(clinicaltrialsModel.toString());
//    }

    /**
     * 1. 在页面输入查询条件，一般是组合条件（Condition or disease + Other terms）
     * 2. 抓取请求中的真实请求，类似：/ct2/results/rpc/ei0yqihHSdCL4Qhzu61gznhLz6hz0Q7xz2hgZdNV9BcHEQhGvB7aUQ7j
     * 3. 将该地址的requestBody复制出来，在firstPage处，填入以上链接
     * 4. 在该地址返回的结果中，取出recordsTotal的数量，以total参数名的形式，填写到postman的x-www-form-urlencoded中
     * http://clinicaltrials.gov
     * @param request
     * @param firstPage
     * @param total
     * @throws Exception
     */
    @PostMapping("search")
    public void searchArticle1(HttpServletRequest request, @RequestParam("firstPage") String firstPage, @RequestParam("total") Integer total) throws Exception {
        List<ClinicaltrialsExcelModel> excelDataList = new ArrayList<>();

//        total = Integer.valueOf(request.getParameter("total"));
        int page = total % 10 == 0 ? total / 10 : total / 10 + 1;
        for (int n = 0; n < page; n++) {
            MultiValueMap<String, String> requestParamMap = new LinkedMultiValueMap<>();
            Map<String, String[]> parameterMap = request.getParameterMap();
            for (String s : parameterMap.keySet()) {
                requestParamMap.add(s, parameterMap.get(s)[0]);
                requestParamMap.remove("start");
            }
            requestParamMap.add("start", n * 10 + "");
            String urlPrefix = "https://clinicaltrials.gov/";
//            String firstPage = request.getParameter("firstPageUrl");
//            String firstPage = "ct2/results/rpc/Zi0yqihHSdCL4Qhzu61gznhLz6hz0Q7xz2hgZdNV9D7xFdcLuQ7GqBcxWwU59VWO";

            HttpHeaders httpHeaders = new HttpHeaders();
            // 模拟form表单发送请求
            httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            HttpEntity<MultiValueMap<String, String>> requestBody = new HttpEntity<>(requestParamMap, httpHeaders);
            ClinicaltrialsModel clinicaltrialsModel = restTemplate.postForObject(urlPrefix + firstPage, requestBody, ClinicaltrialsModel.class);
            String recordsTotal = clinicaltrialsModel.getRecordsTotal();
            List<List<String>> data = clinicaltrialsModel.getData();
            int i = 0;
            for (List<String> dataStrings : data) {
                ClinicaltrialsExcelModel clinicaltrialsExcelModel = new ClinicaltrialsExcelModel();
                Document rowDoc = Jsoup.parse(dataStrings.get(0));
                clinicaltrialsExcelModel.setRowNum(rowDoc.select("body").text());

                clinicaltrialsExcelModel.setIdentifier(dataStrings.get(1));

                Document statusDoc = Jsoup.parse(dataStrings.get(2));
                clinicaltrialsExcelModel.setStatus(statusDoc.select("body").text());

                Document studyTitleDoc = Jsoup.parse(dataStrings.get(3));
                clinicaltrialsExcelModel.setStudyTitle(studyTitleDoc.select("body").text());
                String href = studyTitleDoc.select("a").attr("href");

                Document conditionsDoc = Jsoup.parse(dataStrings.get(4));
                Elements conditionsLi = conditionsDoc.select("li");
                String condition = "";
                for (int m = 1; m <= conditionsLi.size();m++) {
                    String text = conditionsLi.get(m - 1).text();
                    if (!StringUtils.isEmpty(text)){
                        condition +=  m + "." + text + "\n";;
//                    condition += ";" + text;
                    }
                }
                clinicaltrialsExcelModel.setConditions(condition);
//            clinicaltrialsExcelModel.setConditions(condition.replaceFirst(";",""));

//                Document interventionsDoc = Jsoup.parse(dataStrings.get(5));
//                Elements interventionsLi = interventionsDoc.select("li");
//                String interventions = "";
//                for (int m = 1; m <= interventionsLi.size();m++) {
//                    String text = interventionsLi.get(m - 1).text();
//                    if (!StringUtils.isEmpty(text)){
////                    interventions += ";" + text;
//                        interventions += m + "." + text + "\n";
//                    }
//                }
//                clinicaltrialsExcelModel.setInterventions(interventions);
//            clinicaltrialsExcelModel.setInterventions(interventions.replaceFirst(";",""));

                Document sponsor = Jsoup.parse(dataStrings.get(8));
                String sponsor0 = sponsor.select("ul li").get(0).text().trim();
//                String sponsor1 = sponsor.select("ul li span.hit_inf").text().trim();
//                String sponsorStr = sponsor0 + sponsor1;
                clinicaltrialsExcelModel.setSponsor(sponsor0);

                Document locationsDoc = Jsoup.parse(dataStrings.get(dataStrings.size() - 2));
                Elements locationsLi = locationsDoc.select("li");
                String locations = "";
                for (int m = 1; m <= locationsLi.size(); m++) {
                    String text = locationsLi.get(m - 1).text();
                    if (!StringUtils.isEmpty(text)){
//                    locations += ";" + text;
                        locations += m + "." + text + "\n";
                    }
                }
                clinicaltrialsExcelModel.setLocations(locations);
//            clinicaltrialsExcelModel.setLocations(locations.replaceFirst(";",""));

                clinicaltrialsExcelModel.setFirstPosted(dataStrings.get(dataStrings.size() - 5));
                clinicaltrialsExcelModel.setLastUpdatePosted(dataStrings.get(dataStrings.size() - 4));

                String detailUrl = urlPrefix + href;
                System.out.println("href-"+ i++ + ":" + detailUrl);

                Map<String, String> map = new HashMap<>();
                String substring = href.substring(href.indexOf("?") + 1).replace("+"," ");
                for (String s1 : substring.split("&")) {
                    map.put(s1.split("=")[0], s1.split("=")[1]);
                }

                Connection connect = Jsoup.connect(detailUrl);
                Connection.Response response = connect.data(map).method(Connection.Method.GET).ignoreContentType(true).execute();
                Document document = response.parse();
                Element studyDesignTable = document.select("table.ct-layout_table.tr-tableStyle.tr-studyInfo").first();
                Elements studyDesignTableTr = studyDesignTable.select("tbody tr");
                for (Element tr : studyDesignTableTr) {
                    String tdValue1 = tr.select("td").get(0).text().replace(" ","");
                    String tdValue2 = tr.select("td").get(1).text();
                    if (tdValue1.contains("StudyType")){
                        clinicaltrialsExcelModel.setStudyType(tdValue2);
                    } else if (tdValue1.contains("Enrollment")){
                        clinicaltrialsExcelModel.setActualEnrollment(tdValue2);
                    } else if (tdValue1.contains("ObservationalModel")){
//                        clinicaltrialsExcelModel.setObservationalModel(tdValue2);
                    } else if (tdValue1.contains("TimePerspective")){
//                        clinicaltrialsExcelModel.setTimePerspective(tdValue2);
                    } else if (tdValue1.contains("OfficialTitle")){
                        clinicaltrialsExcelModel.setOfficialTitle(tdValue2);
                    }
                }

                Elements tr_indent2Divs = document.select("div.tr-indent1 > div.tr-indent2 > div.tr-indent2");
                for (Element tr_indent2Div : tr_indent2Divs) {
                    Elements tr_indent2Div_ps = tr_indent2Div.select("p[style=margin-top:1ex; margin-bottom:1ex;]");
                    if (!CollectionUtils.isEmpty(tr_indent2Div_ps)) {
                        if ("Inclusion Criteria:".equals(tr_indent2Div_ps.first().text().trim())) {
                            Elements ols = tr_indent2Div.select("ol,ul");
                            if (!CollectionUtils.isEmpty(ols)) {
                                Elements lis = ols.first().select("li");
                                StringBuilder inclusionCriteria = new StringBuilder();
                                for (int m = 1; m <= lis.size(); m++) {
                                    String liText = m + "." + lis.get(m - 1).text().trim() + "\n";
                                    inclusionCriteria.append(liText);
                                }
                                clinicaltrialsExcelModel.setInclusionCriteria(inclusionCriteria.toString());
                                if (ols.size() > 1) {
                                    Elements lis1 = ols.get(1).select("li");
                                    StringBuilder exclusionCriteria = new StringBuilder();
                                    for (int m = 1; m <= lis1.size(); m++) {
                                        String liText = m + "." + lis1.get(m - 1).text().trim() + "\n";
                                        exclusionCriteria.append(liText);
                                    }
                                    clinicaltrialsExcelModel.setExclusionCriteria(exclusionCriteria.toString());
                                }
                            }
                        }
                    }

                }

                Elements style_divs = document.select("div[style=padding-left:.8em; padding-right:1.2em;text-align:left;]");
                for (Element style_div : style_divs) {
                    Elements theads = style_div.select("table thead");
                    if (!CollectionUtils.isEmpty(theads)) {
                        String spanText = theads.select("tr th span").first().text().trim();
                        if ("Arm".equals(spanText)) {
                            Elements tbody_trs = style_div.select("tbody tr");
                            StringBuilder armText = new StringBuilder();
                            StringBuilder intervention = new StringBuilder();
                            for (int x = 1; x <= tbody_trs.size(); x++) {
                                Elements tds = tbody_trs.get(x - 1).select("td");
                                for (int m = 1; m <= tds.size(); m++) {
                                    String divValue = tds.get(m - 1).select("div").text().trim();
                                    String tdText = tds.get(m - 1).text().trim();
                                    if (m % 2 == 0) {
                                        if (!StringUtils.isEmpty(divValue)) {
                                            String armUnit = x + "." + tds.get(m - 1).text().trim() + "\n";
                                            armUnit = armUnit.replace(divValue,"\n\t"+divValue);
                                            intervention.append(armUnit);
                                        } else {
                                            if (!StringUtils.isEmpty(tdText)) {
                                                String armUnit = x + "." + tds.get(m - 1).text().trim() + "\n";
                                                intervention.append(armUnit);
                                            }
                                        }
                                    } else {
                                        if (!StringUtils.isEmpty(divValue)) {
                                            String armUnit = x + "." + tds.get(m - 1).text().trim() + "\n";
                                            armUnit = armUnit.replace(divValue,"\n\t"+divValue);
                                            armText.append(armUnit);
                                        } else {
                                            if (!StringUtils.isEmpty(tdText)) {
                                                String armUnit = x + "." + tds.get(m - 1).text().trim() + "\n";
                                                armText.append(armUnit);
                                            }
                                        }
                                    }

                                }
                            }
                            clinicaltrialsExcelModel.setArms(armText.toString());
                            clinicaltrialsExcelModel.setInterventions(intervention.toString());
                            clinicaltrialsExcelModel.setArmsNumber(String.valueOf(tbody_trs.size()));
                        }
                    }

                }

                Elements div1_div2s = document.select("div.tr-indent1 > div.tr-indent2");
                for (Element div1_div2 : div1_div2s) {
                    String captionText = div1_div2.select("table caption").text().trim();
                    if ("Layout table for eligibility information".equals(captionText)){
                        String ages = div1_div2.select("tbody tr").first().select("td").get(1).text().trim().replace("&nbsp;", "");
                        clinicaltrialsExcelModel.setAgesEligibleForStudy(ages);
                        String sexes = div1_div2.select("tbody tr").get(1).select("td").get(1).text().trim();
                        clinicaltrialsExcelModel.setSexesEligibleForStudy(sexes);
                        String vol = div1_div2.select("tbody tr").get(2).select("td").get(1).text().trim();
                        clinicaltrialsExcelModel.setAcceptsHealthyVolunteers(vol);
                    }
                }

                Elements ct_layout_table_tables = document.select("div#tab-body > div.tr-indent2 > div.tr-indent1 > table.ct-layout_table");
                for (Element ct_layout_table_table : ct_layout_table_tables) {
                    String captionText = ct_layout_table_table.select("caption").text().trim();
                    if ("Layout table for study information".equals(captionText)) {
                        Elements trs = ct_layout_table_table.select("tbody tr");
                        for (Element tr : trs) {
                            String tdText = tr.select("td").first().text().trim();
                            if ("Allocation:".equals(tdText)){
                                String allocation = tr.select("td").last().text().trim();
                                clinicaltrialsExcelModel.setAllocation(allocation);
                            }
                            if ("Masking:".equals(tdText)){
                                String text = tr.select("td").last().text().trim();
                                clinicaltrialsExcelModel.setMasking(text);
                            }
                            if ("Intervention Model:".equals(tdText)){
                                String text = tr.select("td").last().text().trim();
                                clinicaltrialsExcelModel.setInterventionModel(text);
                            }
                            if ("Primary Purpose:".equals(tdText)){
                                String text = tr.select("td").last().text().trim();
                                clinicaltrialsExcelModel.setPrimaryPurpose(text);
                            }
                            if (tdText.contains("Study Start Date :")){
                                String text = tr.select("td").last().text().trim();
                                clinicaltrialsExcelModel.setActualStudyStartDate(text);
                            }
                            if (tdText.contains("Primary Completion Date :")){
                                String text = tr.select("td").last().text().trim();
                                clinicaltrialsExcelModel.setActualPrimaryCompletionDate(text);
                            }
                            if (tdText.contains("Study Completion Date :")){
                                String text = tr.select("td").last().text().trim();
                                clinicaltrialsExcelModel.setActualStudyCompletionDate(text);
                            }
                        }
                    }
                }

                Elements ct_data_table_tables = document.select("div#tab-body > div.tr-indent2 > div.tr-indent1 > div.tr-indent2 > table.ct-data_table");
                for (Element ct_data_table_table : ct_data_table_tables) {
                    Elements tbody_trs = ct_data_table_table.select("tbody tr");
                    if (!CollectionUtils.isEmpty(tbody_trs) && tbody_trs.size() > 1) {
                        Elements tds = tbody_trs.get(1).select("td");
                        if (tds != null && tds.size() >= 3) {
                            String phase = tds.get(2).text().trim();
                            clinicaltrialsExcelModel.setPhase(phase);
                        }
                    }
                }




                // 元素下的子标签使用>表示
                Elements outcomeMeasuresDivSons = document.select("div.tr-indent3 > div.ct-body3");
                for (Element sonDiv : outcomeMeasuresDivSons) {
                    if (sonDiv.select("span").size() < 1){
                        continue;
                    }
                    String spanValue = sonDiv.select("span").first().text();
                    if (spanValue.contains("Primary Outcome Measures")){
                        String primaryOutcomeMeasures = "";
                        Elements ol_li = sonDiv.select("ol li");
                        int j = 0;
                        for (Element element : ol_li) {
                            j++;
                            String li_div = element.select("li div").text();
                            String replace = element.text().replace(li_div, "");
                            primaryOutcomeMeasures += j + "." + replace + "\n";
                        }
                        clinicaltrialsExcelModel.setPrimaryOutcomeMeasures(primaryOutcomeMeasures);
                    } else if (spanValue.contains("Secondary Outcome Measures")){
                        String secondaryOutcomeMeasures = "";
                        Elements ol_li = sonDiv.select("ol li");
                        int j = 0;
                        for (Element element : ol_li) {
                            j++;
                            String li_div = element.select("li div").text();
                            String replace = element.text().replace(li_div, "");
                            secondaryOutcomeMeasures += j + "." + replace + "\n";
                        }
                        clinicaltrialsExcelModel.setSecondaryOutcomeMeasures(secondaryOutcomeMeasures);
                    }
                }

                Elements contactsAndLocationsDivs = document.select("div.ct-header3");
                for (Element contactsAndLocationsDiv : contactsAndLocationsDivs) {
                    String divValue = contactsAndLocationsDiv.text();
                    if ("Sponsors and Collaborators".equals(divValue)){
                        Element element = contactsAndLocationsDiv.nextElementSibling();
                        clinicaltrialsExcelModel.setSponsorsAndCollaborators(element.text());
                    } else if (divValue.contains("Investigators")){
                        Element element = contactsAndLocationsDiv.nextElementSibling();
                        Element tableTr2 = element.select("table tr").get(1);
                        clinicaltrialsExcelModel.setInvestigators(tableTr2.text());
                    }
                }
                excelDataList.add(clinicaltrialsExcelModel);
            }
            Thread.sleep(1000);
        }
        System.out.println("新增数量："+excelDataList.size());
        System.out.println(JSON.toJSONString(excelDataList));
        allExcelDataList.addAll(excelDataList);
        System.out.println("总数量："+excelDataList.size());
    }

//    @PostMapping("insomnia/decoction")
//    public void searchArticle2(HttpServletRequest request) throws Exception {
//        this.searchArticle1(request);
//    }
//    @PostMapping("insomnia/acupuncture")
//    public void searchArticle3(HttpServletRequest request) throws Exception {
//        this.searchArticle1(request);
//    }
//    @PostMapping("insomnia/moxibustion")
//    public void searchArticle4(HttpServletRequest request) throws Exception {
//        this.searchArticle1(request);
//    }
//    @PostMapping("sleeplessness/ChineseMedicine")
//    public void searchArticle5(HttpServletRequest request) throws Exception {
//        this.searchArticle1(request);
//    }
//    @PostMapping("sleeplessness/decoction")
//    public void searchArticle6(HttpServletRequest request) throws Exception {
//        this.searchArticle1(request);
//    }
//    @PostMapping("sleeplessness/acupuncture")
//    public void searchArticle7(HttpServletRequest request) throws Exception {
//        this.searchArticle1(request);
//    }
//    @PostMapping("sleeplessness/moxibustion")
//    public void searchArticle8(HttpServletRequest request) throws Exception {
//        this.searchArticle1(request);
//    }
//    @PostMapping("hyposomnia/ChineseMedicine")
//    public void searchArticle9(HttpServletRequest request) throws Exception {
//        this.searchArticle1(request);
//    }
//    @PostMapping("hyposomnia/decoction")
//    public void searchArticle10(HttpServletRequest request) throws Exception {
//        this.searchArticle1(request);
//    }
//    @PostMapping("hyposomnia/acupuncture")
//    public void searchArticle11(HttpServletRequest request) throws Exception {
//        this.searchArticle1(request);
//    }
//    @PostMapping("hyposomnia/moxibustion")
//    public void searchArticle12(HttpServletRequest request) throws Exception {
//        this.searchArticle1(request);
//    }

    @GetMapping("writeExcel")
    public void writeExcel(){
        System.out.println("去重前总数量："+allExcelDataList.size());
        ArrayList<ClinicaltrialsExcelModel> removeDup = allExcelDataList.stream().collect(Collectors.collectingAndThen(
                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ClinicaltrialsExcelModel::getStudyTitle))), ArrayList::new));
        System.out.println("去重后总数量："+removeDup.size());
        for (int i = 1; i <= removeDup.size(); i++) {
            ClinicaltrialsExcelModel clinicaltrialsExcelModel = removeDup.get(i - 1);
            clinicaltrialsExcelModel.setRowNum(i+"");
        }
        String fileName = "C:\\Users\\hp\\Desktop\\钱多多\\qianduoduo.xlsx";
        write(fileName, ClinicaltrialsExcelModel.class).sheet().head(ClinicaltrialsExcelModel.class)
                .registerWriteHandler(new CustomColumnWidthStrategy())
                .registerWriteHandler(new CustomCellStyleStrategy()).doWrite(removeDup);
        System.out.println("生成excel成功");
    }
}
